/*
 * to use online script you can use jquery getScript plugin as follows:
 *
 * $.getScript('http://sisense.com/abc.js', function(data, textStatus)
 * {
 *		// your code which requires abc.js here
 * });
 *
 * // more info at: http://api.jquery.com/jQuery.getScript/
 *
 */


/*
 * set to true when replacing widget rendering engine.
 */
this.isCustom = true;

/*
 * exectuted after the widget controller was initialized, useful when overriding entire widget in order to instantiate entirely different implementation.
 *
 * @param {args} wraps all function arguments, including widget, dashboard and widget controller instances.
 *
 */
this.init = function (args) {

};

/*
 * executed before the widget query result is loaded to the DOM and allows canceling such beavior and replace it with custom widget implementation.
 * to cancel the default population just set 'args.cancel = true' and the widget default population will be ignored.
 *
 * @param {args} wraps all function arguments, including query result, widget, dashboard and widget controller instances.
 *
 */
this.beforeResultLoaded = function (args) {
};

/*
 * executed after the widget result were added to the DOM. useful to apply DOM tweaks after query result population.
 *
 * @param {args} wraps all function arguments, including query result, widget, dashboard and widget controller instances.
 *
 */
this.afterResultLoaded = function (args) {

    var options = {

        chartType: 'column', // 'line'
        yMin: null,         // sets the max y axis range. Set 'null' to auto-determine.
        yMax: null,         // sets the min y axis range. Set 'null' to auto-determine.
        showLegend: true,   // Turns the legend on/off
        xAxisRotation: 0,   // Sets the rotation in angles of the x Axis labels
        xAxisFontSize: 9,   // Sets the font size of the x Axis labels
        markerRadius: 4     // Sets the radius of the datapoints

    };

    var createGroupedChart = function (args, options) {

        $.getScript('http://localhost/underscore-min.js', function() {

            // 0. Get container info
            var containerId = $(args.element).attr('id');
            var container = $('#'+containerId);
            container.empty();

            var fieldMetaData = args.result.getFieldMetadata();

            // 1. Verify that input is ok for grouped chart
            if (fieldMetaData.length < 3)
                throw 'Source Pivot needs to have at least 3 columns - 2 dimensions, 1 measure.';

            var dim1Column = fieldMetaData[0],
                dim2Column = fieldMetaData[1],
                measureColumns = _.last(fieldMetaData, fieldMetaData.length - 2);

            if (dim1Column.type != 'dimension' || dim2Column.type !== 'dimension')
                throw 'First two columns in Pivot need to be dimensions.';

            if (_.find(measureColumns, function(m) { return m.type != 'measure'} ))
                throw 'The third column and beyond in the Pivot have to be measures.'

            // 2. Put the unique groups and their lengths in 'groupSizes'
            var groupValues = args.result.getCellValues(0),
                groupSizes = {};

            _.each(groupValues, function (g) {

                if (groupSizes[g]) groupSizes[g]++;
                else (groupSizes[g] = 1);
            });

            // 3. Get actual values from second column
            var dim2Values = args.result.getCellValues(1),
                categoryCount = dim2Values.length + _.size(groupSizes) - 1;

            // Helper function to add seperators according to the group sizes.
            var insertSeperators = function (arr, sep) {

                var counter = 0;
                var resultArr = [];

                // 3.2 Insert the values with '' seperators into the dim2Categories array
                _.each(groupSizes, function (size, group) {

                   for (var i = 0; i < size; i++, counter++) {
                       resultArr.push(arr[counter]);
                   }
                   // Insert '' seperator between categories of different group
                   if (counter != arr.length) resultArr.push(sep);
                });
                return resultArr;
            };

            // 4. Create categories array (according to the 2nd dimension)
            var dim2Categories = insertSeperators(dim2Values, ' ');

            // 5. Prepare measures for data series
            //    'measures' is a 2d array. Each entry is an array of data values for one measure.
            var measures = [],
                counter = 0;

            _.each(measureColumns, function (mc) {

                var mValues = _.map(args.result.getCellValues(2 + counter++), function (sVal) {
                    return parseFloat(sVal);
                });
                measures.push( { data: insertSeperators(mValues, null), name: mc.title } );
            });

            // 6. Translate collected values to chart options
            var chartOptions = {};

            // 6.1 measures -> series
            chartOptions.series = [];

            _.each(measures, function (m) {

                chartOptions.series.push( { data: m.data, type: options.chartType, name: m.name } );
            });

            // 6.2 categories
            chartOptions.categories = dim2Categories;

            // 6.3 plotLines & plotBands
            chartOptions.plotBands = [];
            chartOptions.plotLines = [];

            var accumulatedSize = 0;
            _.each(groupSizes, function (size, group) {

                // plotBands
                chartOptions.plotBands.push( {
                    from: accumulatedSize,
                    to: accumulatedSize + size + (accumulatedSize == 0 ? 0 : 1),
                    label: {
                        text: group,
                        align: 'center',
                        verticalAlign: 'top',
                        style: { color: '#666666' }
                    }
                });
                accumulatedSize += size + (accumulatedSize == 0 ? 0 : 1);

                // plotLines
                chartOptions.plotLines.push( {
                    color: '#C0D0E0',
                    dashStyle: 'shortDot',
                    width: 1,
                    value: accumulatedSize
                });
            });
            chartOptions.plotBands[0].from -= 0.5;
            chartOptions.plotBands[chartOptions.plotBands.length - 1].to += 0.5;
            chartOptions.plotLines.pop();

            // Create Chart
            var chart = new Highcharts.Chart({

                chart: {
                    renderTo: containerId
                },
                title: { text: null },
                legend: {
                    enabled: options.showLegend
                },
                xAxis: {
                    categories: chartOptions.categories,
                    min: 3,
                    //plotLines: chartOptions.plotLines,
                    //plotBands: chartOptions.plotBands,
                    labels: {
                        rotation: options.xAxisRotation,
                        style: { fontSize: options.xAxisFontSize } }
                },
                yAxis: {
                    title: { text: null },
                    min: options.yMin,
                    max: options.yMax
                },
                scrollbar: {
                        enabled: true
                },
                series: chartOptions.series,
                plotOptions: {
                    series: {
                        marker: {
                            radius: options.markerRadius
                        }
                    }
                }
            });
        });
    };

    createGroupedChart(args, options);
};

/*
 * exectuted after all dashboard widget models were initialiezed. useful for binding with other widget events.
 *
 * @param {args} wraps all function arguments, including widget, dashboard and widget controller instances.
 *
 */
this.handleDashboardInitialized = function (args) {
};
